/**
 * Copy from main_app.js
 * 
 * modified sth. for nodejs.
 */

const { default: Pool } = require("better-sqlite-pool");
const { Integer } = require("better-sqlite3");

var deribit =
{
    lock_account_page: false,
    environment: "production",
    version_path:"/1.33.0",
    early_init: false,
    ping: true,
    init : {},
    marketMaker: false,
    roles: [],
    anonymous:true,
    tfa_status:-1,
    cod_status: false,
    platform_locked: {"eth":false,"btc":false},
    testnet: false,
    importantAnnouncements: []
}



function initDeribit () {
    log_state("initDeribit");
    if (deribit.init) {
        if ((typeof setClientState) === 'function') {
            log_state("setClientState");
            setClientState("options?tab=all");
            deribit.early_init = true;
            deribit.init = false;
        }
    }
}


function pingDeribit() {
    log_state("pingDeribit");
    if (deribit.ping) {
        if (typeof initPing === 'function') {
            log_state("initPing");
            initPing();
        }
        setTimeout(pingDeribit, 1000);
    } else {
        if (typeof initPing === 'function') {
            initDeribit();
        }
    }
}

function reinitDeribit (state) {
    if ((typeof setClientState) === 'function') {
      if(!state) state = "options?tab=all";
      setClientState(state);
    } else {
        setTimeout(reinitDeribit, 1000);   // a loop ....
    }
}


var lastTradeCallId = 0;
var lastTradePutId = 0;

function scrollTradesCall(){
    if ((typeof reMoreTradesCall) == 'function'){
        let t = lastTradeCallId; // 在 prepLastOpts/appLastOptsCall 内部会更新.
    
        if (t != 0){
            reMoreTradesCall(t);
        } else {
            reMoreTradesCall(0);
        }
    }
    setTimeout(scrollTradesCall, 8000);
}

function scrollTradesPut(){
    if ((typeof reMoreTradesPut) == 'function'){
        let t = lastTradePutId; // 在 prepLastOpts/appLastOptsCall 内部会更新.
    
        if (t != 0){
            reMoreTradesPut(t);
        } else {
            reMoreTradesPut(0);
        }
    }
    setTimeout(scrollTradesPut, 8000);
}

function updateLastTradeCallPutId(arr){
    var arr1 = [], arr2 = [];
    for (i = 0, l = arr.length; i < l; i = i + 1) {
        s = arr[i][0];

        if (null == s.match(/\-P/g)){
            arr1.push(arr[i]); // Calls
        } else {
            arr2.push(arr[i]); // Puts
        }
    }

    if ( arr1.length > 0) {
        lastTradeCallId = updateLastTradeId(arr1, lastTradeCallId);
    }
    if ( arr2.length > 0) {
        lastTradePutId = updateLastTradeId(arr2, lastTradePutId);
    }
}

function updateLastTradeId(array, lastTradeId){
    // 由 fillTable 修改而来
    var max = array.length;
    for (var i = 0; i < max; i++) {
        var d = array[i];
        var tid = d[6];
        if (tid < lastTradeId || lastTradeId === 0) {
            lastTradeId = tid;
        }
    }
    return lastTradeId;
}

/**
 * Format a date like YYYY-MM-DD.
 *
 * @param {string} template
 * @param {Date=} [date]
 * @return {string}
 * @license MIT
 * 
 * Copy from https://gist.github.com/polygonplanet/7952234
 */
function formatDate(template, date) {
    var specs = 'YYYY:MM:DD:HH:mm:ss'.split(':');
    date = new Date(date || Date.now() - new Date().getTimezoneOffset() * 6e4);
    return date.toISOString().split(/[-:.TZ]/).reduce((template, item, i) => {
      return template.split(specs[i]).join(item);
    }, template);
}


function data_persistent(data, type){
    var max = data.length;

    var uni_tid = "SELECT `id` FROM `tb_trades` WHERE `trade_id`=? and `type`=? LIMIT 1;";
    var ddl = "INSERT INTO `tb_trades`(`name`, `price`, `volumn`, `quatity`, `datetime`, `trade_id`, `IV`, `unk`, `type`) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?);";
    var iv_ptn = /^([\d\.]+)/

    dbPool.acquire().then((conn) => {
        ddl = conn.prepare(ddl)
        uni_tid = conn.prepare(uni_tid)

        for (var i=0; i < max; i++) {
            // GT: TODO 这样似乎不能发挥连接池的作用，需要多线程

            var d = data[i];

            d[6] = d[6].toString()

            var res = uni_tid.get(d[6], type);
            if (res) {  // TODO 这里还存在错误，无法判断是否存在
                debug && console.log('[db] - exists record : ' + d[6]);
                continue;
            }

            d[7] = parseFloat(iv_ptn.exec(d[7])[1])

            // "BTC-25JUN21-32000-P","0.0395","0.10","06-04 08:36:58","36636.07",1622795818723,159911665,"101.4&#37;",false
            var res = ddl.run([d[0], d[1], d[4], d[2], formatDate("YYYY-MM-DD HH:mm:ss", d[5]), d[6], d[7], d[8]? 1:0, type]);
            var row_id = res.lastInsertRowid;

            debug && console.log('[db] - insert record: ' + row_id);
        }

        conn.release();
    }).catch((err) => {
        console.error("[db] - ", err);
    });   
}

async function data_callput_persistent(arr){
    var arr1 = [], arr2 = [];
    for (i = 0, l = arr.length; i < l; i = i + 1) {
        s = arr[i][0];

        if (null == s.match(/\-P/g)){
            arr1.push(arr[i]); // Calls
        } else {
            arr2.push(arr[i]); // Puts
        }
    }

    await data_persistent(arr1, 'Call');
    await data_persistent(arr2, 'Put');
}


// 多数需要与服务器交互的 api 都是由 服务器下发后 client 执行 eval 完成。
function optTS(data) { // btc-options.js
    // initStrikesSelect(strike);
    // initDatesSelect(expd);
}
function updOpt(data) {}  // deribit.js, 该函数（$z）用于更新 BTC-Options dashboards.
function updOptSelect(data){}
function setPlatformLocked(currency, value) {}
function optViewInitBegin(){ optInitCurrency('BTC') } // 数据更新核心调用
function stopLoadSpin(){}
function updLastOpts(data){} 
function prepLastOpts(data) {console.log('[prepLastOpts] - ' + JSON.stringify(data)); updateLastTradeCallPutId(data); data_callput_persistent(data); } // deribit.js, 就是需要的数据（由 optInitCurrency 触发下发）
function appLastOptsCall(data) {console.log('[appLastOptsCall] - ' + JSON.stringify(data)); lastTradeCallId = updateLastTradeId(data, lastTradeCallId); data_persistent(data, 'Call'); } // deribit.js，下滑时（reMoreTradesCall）下发数据执行函数.
function appLastOptsPut(data) {console.log('[appLastOptsPut] - ' + JSON.stringify(data)); lastTradePutId = updateLastTradeId(data, lastTradePutId); data_persistent(data, 'Put'); } // deribit.js, 下滑时(reMoreTradesPut) 下发数据执行函数。

module.exports = {deribit, initDeribit, pingDeribit, reinitDeribit, optTS, updOpt, updOptSelect, setPlatformLocked, optViewInitBegin, stopLoadSpin, updLastOpts, prepLastOpts, appLastOptsCall, appLastOptsPut, scrollTradesCall, scrollTradesPut}

